Spring Framework源码(十):SpringMVC之文件上传

    我们这一章讲SpringMVC中文件上传的应用,首先我们还是从DispatcherServlet这个核心分发器开始讲起:

processedRequest = checkMultipart(request);

    还记得上一章讲doDispatch这个方法时见过的方法吧?现在我们来分析下这个方法的具体解析过程:

protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
		//检测multipartResolver是否已经初始化(在initStrategies这个方法中已经初始化了这个处理器),解析request判断是否有文件上传
		if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
			//如果已经在web.xml配置了MultipartFilter过滤器并且已完成了解析则不需要再次处理request
			if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
				logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " +
						"this typically results from an additional MultipartFilter in web.xml");
			}
			//如果在此前解析request的过程中发生了异常则不需要再次处理request
			else if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) instanceof MultipartException) {
				logger.debug("Multipart resolution failed for current request before - " +
						"skipping re-resolution for undisturbed error rendering");
			}
			//非以上情况则解析request
			else {
				return this.multipartResolver.resolveMultipart(request);
			}
		}
		return request;
	}

    以上完成了对request中是否有文件上传的判断,并返回了经过处理的request。但是到底springmvc是怎么解析request的呢?下面我们来看下MultipartResolver接口:

public interface MultipartResolver {
	//判断是否有文件上传
	boolean isMultipart(HttpServletRequest request);
	//解析request
	MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException;
	//清除文件上传内容
	void cleanupMultipart(MultipartHttpServletRequest request);
}

      我们以MultipartResolver的默认实现类StandardServletMultipartResolver为例进行讲解Multipart的解析过程,下面我们来看看isMultipart(HttpServletRequest)和resolveMultipart(HttpServletRequest)两个方法。

public boolean isMultipart(HttpServletRequest request) {
		//检测http的请求方式是否是post
		if (!"post".equals(request.getMethod().toLowerCase())) {
			return false;
		}
		//检查Content-Type,如果是以“multipart”开头则返回真
		String contentType = request.getContentType();
		return (contentType != null && contentType.toLowerCase().startsWith("multipart/"));
	}

     不难看出如果http请求是post方式并且contentType(form标签的enctype="multipart/form-data")是“multipart/form-data”则说明该请求中附带文件需要处理。我们再看看resolveMultipart:

public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
		return new StandardMultipartHttpServletRequest(request, this.resolveLazily);
	}

    它将一个request包装成了一个StandardMultipartHttpServletRequest,这个类会使用parseRequest方法解析http报文,将上传文件封装成StandardMultipartFile挨个存储到MultiValueMap<String, MultipartFile>类型的map中并关联到处理后的request。至于这个map中的file怎么被绑定到controller的参数中我们将在下一章中再做介绍。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值